package com.author.surface;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.ListCellRenderer;
import javax.swing.border.EtchedBorder;

import com.author.document.style.DefaultStyleConstant;
import com.author.document.style.StyleChangeNotify;
import com.author.surface.FontSelectorComboBox.CellRenderer;

public class FontSizeComboBox extends JComboBox implements ActionListener {
	/** Scroll Pane for the Font Sizer combo box */
	private JScrollPane				scrollPane;

	/** Cell Renderer for combo box */
	private ListCellRenderer		cellRenderer;

	/** Width and height of the Font Sizer combo box */
	private static final int		FSIZER_COMBOBOX_WIDTH	= 55;
	private static final int		FSIZER_COMBOBOX_HEIGHT	= 25;
	private static final int		ROW_COUNT				= 16;

	/**
	 * Size of the font using which the numbers inside the Font Sizer combo box
	 * will be displayed.
	 */
	private static final int		SIZE_OF_FONT			= 13;

	/** Font which will be used to display the contents of the Font Sizer box */
	private static final String		DEFAULT_FONT_NAME		= DefaultStyleConstant.DEFAULT_STYLE_FONT_NAME;

	/** List of available FONT SIZES */
	public static final Object[]	FONT_SIZE				= { "9", "10",
			"11", "12", "14", "16", "18", "20", "22", "24", "26", "28", "32",
			"36", "40", "44", "48", "54", "60", "66", "72", "80", "88", "96" };

	/** Add a delta to the font size, otherwise the fonts will appear small */
	public static final int			DELTA					= 6;

	/** Current font size */
	private int						currentFontSize			= DefaultStyleConstant
																	.getFontSizeForStyleName(DefaultStyleConstant.DEFAULT_STYLE);

	public FontSizeComboBox(Object[] fontsize) throws Exception {
		super(fontsize);

		// Set size of the combo box
		setSize(new Dimension(FontSizeComboBox.FSIZER_COMBOBOX_WIDTH,
				FontSizeComboBox.FSIZER_COMBOBOX_HEIGHT));
		setPreferredSize(getSize());

		// Set Cell Renderer of the combo box
		cellRenderer = new CellRenderer();
		setRenderer(cellRenderer);

		// Add scroll pane and set its viewport
		scrollPane = new JScrollPane(this);
		scrollPane.setViewport(new JViewport());
		scrollPane.getViewport().setView(this);

		// The Font Sizer combo box will display a font size of 10 initially,
		// which is present at index 1
		setSelectedIndex(1);
		setFont(new Font(DEFAULT_FONT_NAME, Font.PLAIN, SIZE_OF_FONT));
		setBackground(Color.WHITE);
		setToolTipText("FONT SIZE");

		// Set auxiliary properties of the combo box
		setFocusable(false);
		setVisible(true);
		addActionListener(this);
	}

	/**
	 * This method will be executed when the UI updater requests that the Font
	 * Sizer Combo Box displays a different sized font then the font size that
	 * it is currently displaying
	 * 
	 * @param Size
	 *            font which should be displayed
	 */
	public void setFontSize(int fontSize) {
		int indexPos = getFontSizeIndex(fontSize - DELTA);
		String selectedSize = (String) FONT_SIZE[indexPos];
		currentFontSize = Integer.parseInt(selectedSize)
				+ FontSizeComboBox.DELTA;

		// set selected index and tool tip text to reflect new font size
		setSelectedIndex(indexPos);
		setToolTipText(String.valueOf(currentFontSize));
	}

	/**
	 * Returns the index position for a font of given size
	 */
	private int getFontSizeIndex(int fontSize) {
		int len = FONT_SIZE.length;
		for (int i = 0; i < len; i++) {
			int value = Integer.parseInt((String) FONT_SIZE[i]);
			if (value != fontSize) continue;
			return i;
		}
		return -1;
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource() instanceof JComboBox) {
			JComboBox cb = (JComboBox) e.getSource();
			int selectedItemIndex = cb.getSelectedIndex();
			String selectedSize = (String) cb.getItemAt(selectedItemIndex);

			// Update font size and inform notifier to reflect change in
			// TextPane
			int previousFontSize = currentFontSize;
			currentFontSize = Integer.parseInt(selectedSize)
					+ FontSizeComboBox.DELTA; // without this fonts appear very
												// small
			StyleChangeNotify styleChangeNotify = StyleChangeNotify
					.getStyleChangeNotify();
			styleChangeNotify.setDocumentFontSizeChange(previousFontSize,
					currentFontSize);
		}
	}

	protected class CellRenderer extends JLabel implements ListCellRenderer {
		/** Width and height of each cell of the FSizer combo box */
		private static final int	CELL_WIDTH	= 50;
		private static final int	CELL_HEIGHT	= 25;

		/** Font used to display the items inside the Cell Renderer */
		private Font				font;

		protected CellRenderer() {
			// Set Cell Renderer size
			setSize(new Dimension(CELL_WIDTH, CELL_HEIGHT));
			setPreferredSize(getSize());
			setOpaque(true);

			// Set alignment
			setHorizontalAlignment(LEFT);
			setVerticalAlignment(CENTER);

			// Set tool tip text and font
			font = new Font(FontSizeComboBox.DEFAULT_FONT_NAME, Font.PLAIN,
					SIZE_OF_FONT);
			setToolTipText("Size of FONT");
			setFont(font);
		}

		/**
		 * Respond to user selection of a font size selection
		 */
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean hasFocus) {
			String s = (String) value;
			setText((String) s);

			if (isSelected) {
				setBackground(list.getSelectionBackground());
				setForeground(list.getSelectionForeground());
			} else {
				setBackground(list.getBackground());
				setForeground(list.getForeground());
			}
			return this;
		}
	}

}
